/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sk.lieskove.jianghongtiao.common.utils.text;

import org.apache.log4j.Logger;
import sk.lieskove.jianghongtiao.common.utils.PropertiesUtils;

import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;

/**
 * 
 * @author xjuraj e-mail: jjurco.sk_gmail.com
 */
public class Diacritics implements Serializable {

    private transient Logger log = Logger.getLogger(Diacritics.class);
    private transient PropertiesUtils pu = new PropertiesUtils(Diacritics.class);
    private transient static final Map<String, Pattern> diacritics = new TreeMap<String, Pattern>();
    public transient static final String DIACRITICS_a = "áàăắằẵẳâấầẫẩǎåǻäǟãȧǡąāảȁȃạặậḁⱥᶏɐɑ";
    public transient static final String DIACRITICS_A = "ÁÀĂẮẰẴẲÂẤẦẪẨǍÅǺÄǞÃȦǠĄĀẢȀȂẠẶẬḀȺⱯⱭ";
    public transient static final String DIACRITICS_b = "ḃḅḇƀɓƃᵬᶀ";
    public transient static final String DIACRITICS_B = "ḂḄḆɃƁƂ";
    public transient static final String DIACRITICS_c = "ćĉčċçḉȼƈɕ";
    public transient static final String DIACRITICS_C = "ĆĈČĊÇḈȻƇ";
    public transient static final String DIACRITICS_d = "ďḋḑḍḓḏđɖɗƌᵭᶁᶑȡ∂";
    public transient static final String DIACRITICS_D = "ĎḊḐḌḒḎĐƉƊƋ";
    public transient static final String DIACRITICS_e = "éèĕêếềễểěëẽėȩḝęēḗḕẻȅȇẹệḙḛɇᶒⱸ";
    public transient static final String DIACRITICS_E = "ÉÈĔÊẾỀỄỂĚËẼĖȨḜĘĒḖḔẺȄȆẸỆḘḚɆ"; 	
    public transient static final String DIACRITICS_f = "ḟƒᵮᶂ";
    public transient static final String DIACRITICS_F = "ḞƑ";
    public transient static final String DIACRITICS_g = "ǵğĝǧġģḡǥɠᶃ";
    public transient static final String DIACRITICS_G = "ǴĞĜǦĠĢḠǤƓ";
    public transient static final String DIACRITICS_h = "ĥȟḧḣḩḥḫẖħⱨ";
    public transient static final String DIACRITICS_H = "ĤȞḦḢḨḤḪĦⱧ";
    public transient static final String DIACRITICS_i = "íìĭîǐïḯĩįīỉȉȋịḭɨᵻᶖı";
    public transient static final String DIACRITICS_I = "ÍÌĬÎǏÏḮĨĮĪỈȈȊỊḬƗİ";
    public transient static final String DIACRITICS_j = "ĵɉǰȷʝɟʄ";
    public transient static final String DIACRITICS_J = "ĴɈ";
    public transient static final String DIACRITICS_k = "ḱǩķḳḵƙⱪᶄꝁ";
    public transient static final String DIACRITICS_K = "ḰǨĶḲḴƘⱩꝀ";
    public transient static final String DIACRITICS_l = "ĺľļḷḹḽḻłŀƚⱡɫɬᶅɭȴ";
    public transient static final String DIACRITICS_L = "ĹĽĻḶḸḼḺŁĿȽⱠⱢ";
    public transient static final String DIACRITICS_m = "ḿṁṃᵯᶆɱ";
    public transient static final String DIACRITICS_M = "ḾṀṂⱮ";
    public transient static final String DIACRITICS_n = "ńǹňñṅņṇṋṉɲƞŋꞑᵰᶇɳȵ";
    public transient static final String DIACRITICS_N = "ŃǸŇÑṄŅṆṊṈƝȠŊꞐ";
    public transient static final String DIACRITICS_o = "óòŏôốồỗổǒöȫőõṍṏȭȯȱøǿǫǭōṓṑỏȍȏơớờỡởợọộɵɔⱺ";
    public transient static final String DIACRITICS_O = "ÓÒŎÔỐỒỖỔǑÖȪŐÕṌṎȬȮȰØǾǪǬŌṒṐỎȌȎƠỚỜỠỞỢỌỘƟƆ";
    public transient static final String DIACRITICS_p = "ṕṗᵽƥᵱᶈ";
    public transient static final String DIACRITICS_P = "ṔṖⱣƤ";
    public transient static final String DIACRITICS_q = "ɋƣʠ";
    public transient static final String DIACRITICS_Q = "ɊƢ";
    public transient static final String DIACRITICS_r = "ŕřṙŗȑȓṛṝṟɍɽᵲᶉɼɾᵳ";
    public transient static final String DIACRITICS_R = "ŔŘṘŖȐȒṚṜṞɌⱤ";
    public transient static final String DIACRITICS_s = "śṥŝšṧṡẛşṣṩșᵴᶊʂȿ";
    public transient static final String DIACRITICS_S = "ŚṤŜŠṦṠŞṢṨȘ";
    public transient static final String DIACRITICS_t = "ťṫţṭțṱṯŧⱦƭʈẗᵵƫȶ";
    public transient static final String DIACRITICS_T = "ŤṪŢṬȚṰṮŦȾƬƮ";
    public transient static final String DIACRITICS_u = "úùŭûǔůüǘǜǚǖűũṹųūṻủȕȗưứừữửựụṳṷṵʉᵾᶙ";
    public transient static final String DIACRITICS_U = "ÚÙŬÛǓŮÜǗǛǙǕŰŨṸŲŪṺỦȔȖƯỨỪỮỬỰỤṲṶṴɄ";
    public transient static final String DIACRITICS_v = "ṽṿʋᶌⱱⱴ";
    public transient static final String DIACRITICS_V = "ṼṾƲ";
    public transient static final String DIACRITICS_w = "ⱳẘẃẁŵẅẇẉ";
    public transient static final String DIACRITICS_W = "ẂẀŴẄẆẈⱲ";
    public transient static final String DIACRITICS_x = "ẍẋᶍ";
    public transient static final String DIACRITICS_X = "ẌẊ";
    public transient static final String DIACRITICS_y = "ýỳŷẙÿỹẏȳỷỵɏƴʏ";
    public transient static final String DIACRITICS_Y = "ÝỲŶŸỸẎȲỶỴɎƳ";
    public transient static final String DIACRITICS_z = "źẑžżẓẕƶȥⱬᵶᶎʐʑɀ";
    public transient static final String DIACRITICS_Z = "ŹẐŽŻẒẔƵȤⱫ";
    public transient static final String SPECIAL_CHARACTERS = "̩̩̱̱̃̌̊̈̈̈̊͘"; //string contains (a lot of) invisible characters
    public transient static final Map<String, String> DIACRITICS_MAP = new TreeMap<String, String>();
    private transient static final Pattern a = Pattern.compile("[" + DIACRITICS_a + "]");
    private transient static final Pattern A = Pattern.compile("[" + DIACRITICS_A + "]");
    private transient static final Pattern b = Pattern.compile("[" + DIACRITICS_b + "]");
    private transient static final Pattern B = Pattern.compile("[" + DIACRITICS_B + "]");
    private transient static final Pattern c = Pattern.compile("[" + DIACRITICS_c + "]");
    private transient static final Pattern C = Pattern.compile("[" + DIACRITICS_C + "]");
    private transient static final Pattern d = Pattern.compile("[" + DIACRITICS_d + "]");
    private transient static final Pattern D = Pattern.compile("[" + DIACRITICS_D + "]");
    private transient static final Pattern e = Pattern.compile("[" + DIACRITICS_e + "]");
    private transient static final Pattern E = Pattern.compile("[" + DIACRITICS_E + "]");
    private transient static final Pattern f = Pattern.compile("[" + DIACRITICS_f + "]");
    private transient static final Pattern F = Pattern.compile("[" + DIACRITICS_F + "]");
    private transient static final Pattern g = Pattern.compile("[" + DIACRITICS_g + "]");
    private transient static final Pattern G = Pattern.compile("[" + DIACRITICS_G + "]");
    private transient static final Pattern h = Pattern.compile("[" + DIACRITICS_h + "]");
    private transient static final Pattern H = Pattern.compile("[" + DIACRITICS_H + "]");
    private transient static final Pattern i = Pattern.compile("[" + DIACRITICS_i + "]");
    private transient static final Pattern I = Pattern.compile("[" + DIACRITICS_I + "]");
    private transient static final Pattern j = Pattern.compile("[" + DIACRITICS_j + "]");
    private transient static final Pattern J = Pattern.compile("[" + DIACRITICS_J + "]");
    private transient static final Pattern k = Pattern.compile("[" + DIACRITICS_k + "]");
    private transient static final Pattern K = Pattern.compile("[" + DIACRITICS_K + "]");
    private transient static final Pattern l = Pattern.compile("[" + DIACRITICS_l + "]");
    private transient static final Pattern L = Pattern.compile("[" + DIACRITICS_L + "]");
    private transient static final Pattern m = Pattern.compile("[" + DIACRITICS_m + "]");
    private transient static final Pattern M = Pattern.compile("[" + DIACRITICS_M + "]");
    private transient static final Pattern n = Pattern.compile("[" + DIACRITICS_n + "]");
    private transient static final Pattern N = Pattern.compile("[" + DIACRITICS_N + "]");
    private transient static final Pattern o = Pattern.compile("[" + DIACRITICS_o + "]");
    private transient static final Pattern O = Pattern.compile("[" + DIACRITICS_O + "]");
    private transient static final Pattern p = Pattern.compile("[" + DIACRITICS_p + "]");
    private transient static final Pattern P = Pattern.compile("[" + DIACRITICS_P + "]");
    private transient static final Pattern q = Pattern.compile("[" + DIACRITICS_q + "]");
    private transient static final Pattern Q = Pattern.compile("[" + DIACRITICS_Q + "]");
    private transient static final Pattern r = Pattern.compile("[" + DIACRITICS_r + "]");
    private transient static final Pattern R = Pattern.compile("[" + DIACRITICS_R + "]");
    private transient static final Pattern s = Pattern.compile("[" + DIACRITICS_s + "]");
    private transient static final Pattern S = Pattern.compile("[" + DIACRITICS_S + "]");
    private transient static final Pattern t = Pattern.compile("[" + DIACRITICS_t + "]");
    private transient static final Pattern T = Pattern.compile("[" + DIACRITICS_T + "]");
    private transient static final Pattern u = Pattern.compile("[" + DIACRITICS_u + "]");
    private transient static final Pattern U = Pattern.compile("[" + DIACRITICS_U + "]");
    private transient static final Pattern v = Pattern.compile("[" + DIACRITICS_v + "]");
    private transient static final Pattern V = Pattern.compile("[" + DIACRITICS_V + "]");
    private transient static final Pattern w = Pattern.compile("[" + DIACRITICS_w + "]");
    private transient static final Pattern W = Pattern.compile("[" + DIACRITICS_W + "]");
    private transient static final Pattern x = Pattern.compile("[" + DIACRITICS_x + "]");
    private transient static final Pattern X = Pattern.compile("[" + DIACRITICS_X + "]");
    private transient static final Pattern y = Pattern.compile("[" + DIACRITICS_y + "]");
    private transient static final Pattern Y = Pattern.compile("[" + DIACRITICS_Y + "]");
    private transient static final Pattern z = Pattern.compile("[" + DIACRITICS_z + "]");
    private transient static final Pattern Z = Pattern.compile("[" + DIACRITICS_Z + "]");

    static {
        diacritics.put("A", A);
        diacritics.put("B", B);
        diacritics.put("C", C);
        diacritics.put("D", D);
        diacritics.put("E", E);
        diacritics.put("F", F);
        diacritics.put("G", G);
        diacritics.put("H", H);
        diacritics.put("I", I);
        diacritics.put("J", J);
        diacritics.put("K", K);
        diacritics.put("L", L);
        diacritics.put("M", M);
        diacritics.put("N", N);
        diacritics.put("O", O);
        diacritics.put("P", P);
        diacritics.put("Q", Q);
        diacritics.put("R", R);
        diacritics.put("S", S);
        diacritics.put("T", T);
        diacritics.put("U", U);
        diacritics.put("V", V);
        diacritics.put("W", W);
        diacritics.put("X", X);
        diacritics.put("Y", Y);
        diacritics.put("Z", Z);
        diacritics.put("a", a);
        diacritics.put("b", b);
        diacritics.put("c", c);
        diacritics.put("d", d);
        diacritics.put("e", e);
        diacritics.put("f", f);
        diacritics.put("g", g);
        diacritics.put("h", h);
        diacritics.put("i", i);
        diacritics.put("j", j);
        diacritics.put("k", k);
        diacritics.put("l", l);
        diacritics.put("m", m);
        diacritics.put("n", n);
        diacritics.put("o", o);
        diacritics.put("p", p);
        diacritics.put("q", q);
        diacritics.put("r", r);
        diacritics.put("s", s);
        diacritics.put("t", t);
        diacritics.put("u", u);
        diacritics.put("v", v);
        diacritics.put("w", w);
        diacritics.put("x", x);
        diacritics.put("y", y);
        diacritics.put("z", z);
        
        DIACRITICS_MAP.put("A", DIACRITICS_A);
        DIACRITICS_MAP.put("B", DIACRITICS_B);
        DIACRITICS_MAP.put("C", DIACRITICS_C);
        DIACRITICS_MAP.put("D", DIACRITICS_D);
        DIACRITICS_MAP.put("E", DIACRITICS_E);
        DIACRITICS_MAP.put("F", DIACRITICS_F);
        DIACRITICS_MAP.put("G", DIACRITICS_G);
        DIACRITICS_MAP.put("H", DIACRITICS_H);
        DIACRITICS_MAP.put("I", DIACRITICS_I);
        DIACRITICS_MAP.put("J", DIACRITICS_J);
        DIACRITICS_MAP.put("K", DIACRITICS_K);
        DIACRITICS_MAP.put("L", DIACRITICS_L);
        DIACRITICS_MAP.put("M", DIACRITICS_M);
        DIACRITICS_MAP.put("N", DIACRITICS_N);
        DIACRITICS_MAP.put("O", DIACRITICS_O);
        DIACRITICS_MAP.put("P", DIACRITICS_P);
        DIACRITICS_MAP.put("Q", DIACRITICS_Q);
        DIACRITICS_MAP.put("R", DIACRITICS_R);
        DIACRITICS_MAP.put("S", DIACRITICS_S);
        DIACRITICS_MAP.put("T", DIACRITICS_T);
        DIACRITICS_MAP.put("U", DIACRITICS_U);
        DIACRITICS_MAP.put("V", DIACRITICS_V);
        DIACRITICS_MAP.put("W", DIACRITICS_W);
        DIACRITICS_MAP.put("X", DIACRITICS_X);
        DIACRITICS_MAP.put("Y", DIACRITICS_Y);
        DIACRITICS_MAP.put("Z", DIACRITICS_Z);
        DIACRITICS_MAP.put("a", DIACRITICS_a);
        DIACRITICS_MAP.put("b", DIACRITICS_b);
        DIACRITICS_MAP.put("c", DIACRITICS_c);
        DIACRITICS_MAP.put("d", DIACRITICS_d);
        DIACRITICS_MAP.put("e", DIACRITICS_e);
        DIACRITICS_MAP.put("f", DIACRITICS_f);
        DIACRITICS_MAP.put("g", DIACRITICS_g);
        DIACRITICS_MAP.put("h", DIACRITICS_h);
        DIACRITICS_MAP.put("i", DIACRITICS_i);
        DIACRITICS_MAP.put("j", DIACRITICS_j);
        DIACRITICS_MAP.put("k", DIACRITICS_k);
        DIACRITICS_MAP.put("l", DIACRITICS_l);
        DIACRITICS_MAP.put("m", DIACRITICS_m);
        DIACRITICS_MAP.put("n", DIACRITICS_n);
        DIACRITICS_MAP.put("o", DIACRITICS_o);
        DIACRITICS_MAP.put("p", DIACRITICS_p);
        DIACRITICS_MAP.put("q", DIACRITICS_q);
        DIACRITICS_MAP.put("r", DIACRITICS_r);
        DIACRITICS_MAP.put("s", DIACRITICS_s);
        DIACRITICS_MAP.put("t", DIACRITICS_t);
        DIACRITICS_MAP.put("u", DIACRITICS_u);
        DIACRITICS_MAP.put("v", DIACRITICS_v);
        DIACRITICS_MAP.put("w", DIACRITICS_w);
        DIACRITICS_MAP.put("x", DIACRITICS_x);
        DIACRITICS_MAP.put("y", DIACRITICS_y);
        DIACRITICS_MAP.put("z", DIACRITICS_z);
    }

    public static String removeSpecialDiacriticSigns(String text) {
        return text.replaceAll("[" + SPECIAL_CHARACTERS + "]", "");
    }

    public static String removeDiacritics(String text){
        String replace = text;
        for (Iterator it = diacritics.keySet().iterator(); it.hasNext();) {
            String repl = (String) it.next();
            Pattern patt = diacritics.get(repl);
            replace = patt.matcher(replace).replaceAll(repl);
        }
        return replace;
    }

    public static boolean containsDiacritics(String text) {
        return a.matcher(text).matches() || A.matcher(text).matches()
                || e.matcher(text).matches() || E.matcher(text).matches()
                || i.matcher(text).matches() || I.matcher(text).matches()
                || o.matcher(text).matches() || O.matcher(text).matches()
                || u.matcher(text).matches() || U.matcher(text).matches()
                || c.matcher(text).matches() || C.matcher(text).matches()
                || d.matcher(text).matches() || D.matcher(text).matches()
                || n.matcher(text).matches() || N.matcher(text).matches()
                || l.matcher(text).matches() || L.matcher(text).matches()
                || f.matcher(text).matches() || F.matcher(text).matches()
                || r.matcher(text).matches() || R.matcher(text).matches()
                || v.matcher(text).matches() || V.matcher(text).matches()
                || s.matcher(text).matches() || S.matcher(text).matches()
                || t.matcher(text).matches() || T.matcher(text).matches()
                || y.matcher(text).matches() || Y.matcher(text).matches()
                || z.matcher(text).matches() || Z.matcher(text).matches()
                || b.matcher(text).matches() || B.matcher(text).matches()
                || g.matcher(text).matches() || G.matcher(text).matches()
                || h.matcher(text).matches() || H.matcher(text).matches()
                || j.matcher(text).matches() || J.matcher(text).matches()
                || k.matcher(text).matches() || K.matcher(text).matches()
                || m.matcher(text).matches() || M.matcher(text).matches()
                || p.matcher(text).matches() || P.matcher(text).matches()
                || q.matcher(text).matches() || Q.matcher(text).matches()
                || w.matcher(text).matches() || W.matcher(text).matches()
                || x.matcher(text).matches() || X.matcher(text).matches();
    }
}
